import * as vscode from 'vscode'

/**
 * 文档符号提供者类
 * 为4GL语言提供文档符号（如函数、报表等）识别功能
 */
export class MyDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
	/**
	 * 格式化函数名称函数
	 * 从函数声明中提取函数名称
	 * @param cmd 函数声明字符串
	 * @returns 函数名称
	 */
	private formatFunc(cmd: string): string {
		return cmd
			.replace(/^ *(private )?function /i, "")
			.replace(/\(.*/, "")
			.trim()
	}

	/**
	 * 格式化报表名称函数
	 * 从报表声明中提取报表名称
	 * @param cmd 报表声明字符串
	 * @returns 报表名称
	 */
	private formatRep(cmd: string): string {
		return cmd
			.replace(/^ *report /i, "")
			.replace(/\(.*/, "")
			.trim()
	}

	/**
	 * 创建符号函数
	 * 创建文档符号对象
	 * @param name 符号名称
	 * @param detail 符号详细信息
	 * @param kind 符号类型
	 * @param range 符号范围
	 * @returns 文档符号对象
	 */
	private createSymbol(
		name: string,
		detail: string,
		kind: vscode.SymbolKind,
		range: vscode.Range
	): vscode.DocumentSymbol {
		return new vscode.DocumentSymbol(name, detail, kind, range, range)
	}

	/**
	 * 提供文档符号函数
	 * 识别并返回文档中的符号
	 * @param document 当前文档
	 * @param token 取消令牌
	 * @returns 文档符号数组
	 */
	provideDocumentSymbols(
		document: vscode.TextDocument, 
		token: vscode.CancellationToken
	): vscode.ProviderResult<vscode.SymbolInformation[] | vscode.DocumentSymbol[]> {
		return new Promise((resolve) => {
			const symbols: vscode.DocumentSymbol[] = []
			const nodes = [symbols]
			
			/**
			 * 符号模式定义
			 * 定义各种符号的识别模式和处理方式
			 */
			const symbolPatterns = {
				function: {
					regex: /^ *(?:private )?function /i,
					format: (text: string) => this.formatFunc(text),
					kind: vscode.SymbolKind.Function,
					detail: ""
				},
				report: {
					regex: /^ *report /i,
					format: (text: string) => this.formatRep(text),
					kind: vscode.SymbolKind.Function,
					detail: "Report"
				},
				main: {
					regex: /^MAIN/,
					format: () => "MAIN",
					kind: vscode.SymbolKind.Function,
					detail: "MAIN statement"
				},
				globals: {
					regex: /^GLOBALS/,
					format: () => "GLOBALS",
					kind: vscode.SymbolKind.Key,
					detail: ""
				}
			}

			// 遍历文档中的每一行
			for (let i = 0; i < document.lineCount; i++) {
				const line = document.lineAt(i)
				
				// 检查每种符号模式
				for (const [_, pattern] of Object.entries(symbolPatterns)) {
					if (line.text.match(pattern.regex)) {
						nodes[nodes.length - 1].push(
							this.createSymbol(
								pattern.format(line.text),
								pattern.detail,
								pattern.kind,
								line.range
							)
						)
						break
					}
				}
			}
			
			resolve(symbols)
		})
	}
}